<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Tutorial</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2">
<link rel="start" href="../index.html" title="RCF User Guide">
<link rel="up" href="../index.html" title="RCF User Guide">
<link rel="prev" href="Intro.html" title="Introduction">
<link rel="next" href="Clientside.html" title="Remote Calls - Client-side">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
<a accesskey="p" href="Intro.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="Clientside.html"><img src="../images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="rcf_user_guide.Tutorial"></a><a class="link" href="Tutorial.html" title="Tutorial"> Tutorial</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted"> Getting started</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.Interfaces"> Interfaces and implementations</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.Errors"> Error handling</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.ClientStubs"> Client stubs</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.server_sessions">Server sessions</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.Transports"> Transports</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.TransportProtocols"> Transport
      protocols</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.Threading"> Server-side threading</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls">Asynchronous
      remote calls</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.PubSub"> Publish/subscribe</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.callback_connections">Callback
      connections</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.file_transfers">File transfers</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.Protobufs"> Protocol Buffers</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.json_rpc">JSON-RPC</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.GettingStarted"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted" title="Getting started"> Getting started</a>
</h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.hello_world">Hello
        World</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.how_to_build___visual_studio_2010">How
        to build - Visual Studio 2010</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.how_to_build___gcc">How
        to build - gcc</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.running_the_server_and_client">Running
        the server and client</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.GettingStarted.hello_world"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.hello_world" title="Hello World">Hello
        World</a>
</h4></div></div></div>
<p>
          Following programming language traditions, let's start with a "Hello
          World" example. We'll write a client that sends strings to a server,
          and a server that prints the strings to standard output.
        </p>
<p>
          Here is the server:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>


<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
    
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Press Enter to exit..."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>

    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>

</pre>
<p>
        </p>
<p>
          And the client:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Calling the I_HelloWorld Print() method."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>

</pre>
<p>
        </p>
<p>
          The transport used is a TCP connection, with the server listening on port
          50001 of the localhost (<code class="computeroutput"><span class="number">127.0</span><span class="special">.</span><span class="number">0.1</span></code>) interface.
        </p>
</div>
<p>
        Before we can run this code, we need to build it. To build RCF, you simply
        need to compile the <code class="computeroutput"><span class="identifier">src</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">cpp</span></code> source
        file into your application. RCF requires the <a href="http://www.boost.org" target="_top">Boost</a>
        library to be available, so you will need to download Boost. Any version
        from 1.35.0 onwards will do. You do not need to build any Boost libraries,
        as RCF will in its default configuration only use header files from Boost.
      </p>
<p>
        Here is how you would build the server code above, with two common compiler
        toolsets.
      </p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.GettingStarted.how_to_build___visual_studio_2010"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.how_to_build___visual_studio_2010" title="How to build - Visual Studio 2010">How
        to build - Visual Studio 2010</a>
</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li>
              In the Visual Studio IDE, select <code class="computeroutput"><span class="identifier">New</span>
              <span class="identifier">Project</span> <span class="special">-&gt;</span>
              <span class="identifier">Visual</span> <span class="identifier">C</span><span class="special">++</span> <span class="special">-&gt;</span> <span class="identifier">Win32</span> <span class="special">-&gt;</span>
              <span class="identifier">Win32</span> <span class="identifier">Console</span>
              <span class="identifier">Application</span></code>
            </li>
<li>
              In the <code class="computeroutput"><span class="identifier">Application</span> <span class="identifier">Settings</span></code> dialog, check the <code class="computeroutput"><span class="identifier">Empty</span> <span class="identifier">Project</span></code>
              checkbox.
            </li>
<li>
              In the <code class="computeroutput"><span class="identifier">Project</span> <span class="identifier">Properties</span></code>
              dialog for the new project, select <code class="computeroutput"><span class="identifier">C</span><span class="special">/</span><span class="identifier">C</span><span class="special">++</span> <span class="special">-&gt;</span> <span class="identifier">General</span> <span class="special">-&gt;</span>
              <span class="identifier">Additional</span> <span class="identifier">Include</span>
              <span class="identifier">Directories</span></code>.
            </li>
<li>
              Add the include paths for Boost and RCF, e.g. <code class="computeroutput"><span class="identifier">C</span><span class="special">:\</span><span class="identifier">boost_1_49_0</span></code>
              and <code class="computeroutput"><span class="identifier">C</span><span class="special">:\</span><span class="identifier">RCF</span><span class="special">\</span><span class="identifier">include</span></code>.
            </li>
<li>
              Add a file <code class="computeroutput"><span class="identifier">Server</span><span class="special">.</span><span class="identifier">cpp</span></code> to the project, and copy-paste
              the code above into it.
            </li>
<li>
              Add <code class="computeroutput"><span class="identifier">RCF</span><span class="special">\</span><span class="identifier">src</span><span class="special">\</span><span class="identifier">RCF</span><span class="special">\</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">cpp</span></code> to the project.
            </li>
<li>
              Select <code class="computeroutput"><span class="identifier">Build</span> <span class="special">-&gt;</span>
              <span class="identifier">Build</span> <span class="identifier">Solution</span></code>.
            </li>
</ul></div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.GettingStarted.how_to_build___gcc"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.how_to_build___gcc" title="How to build - gcc">How
        to build - gcc</a>
</h4></div></div></div>
<div class="itemizedlist"><ul type="disc">
<li>
              Create a file <code class="computeroutput"><span class="identifier">Server</span><span class="special">.</span><span class="identifier">cpp</span></code>
              and copy-paste the code above into it.
            </li>
<li>
              From the same directory, run the following command:
            </li>
</ul></div>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">g</span><span class="special">++</span> <span class="identifier">Server</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">/</span><span class="identifier">path</span><span class="special">/</span><span class="identifier">to</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">src</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">-</span><span class="identifier">I</span><span class="special">/</span><span class="identifier">path</span><span class="special">/</span><span class="identifier">to</span><span class="special">/</span><span class="identifier">boost_1_49_0</span> <span class="special">-</span><span class="identifier">I</span><span class="special">/</span><span class="identifier">path</span><span class="special">/</span><span class="identifier">to</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">include</span> <span class="special">-</span><span class="identifier">lpthread</span> <span class="special">-</span><span class="identifier">ldl</span> <span class="special">-</span><span class="identifier">oServer</span>
</pre>
<p>
          , replacing <code class="computeroutput"><span class="special">/</span><span class="identifier">path</span><span class="special">/</span><span class="identifier">to</span><span class="special">/</span><span class="identifier">boost_1_49_0</span></code> and <code class="computeroutput"><span class="special">/</span><span class="identifier">path</span><span class="special">/</span><span class="identifier">to</span><span class="special">/</span><span class="identifier">RCF</span></code>
          with the actual paths on your system.
        </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.GettingStarted.running_the_server_and_client"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.GettingStarted.running_the_server_and_client" title="Running the server and client">Running
        the server and client</a>
</h4></div></div></div>
<p>
          Let's start the server:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">c</span><span class="special">:\</span><span class="identifier">Projects</span><span class="special">\</span><span class="identifier">RcfSample</span><span class="special">\</span><span class="identifier">Debug</span><span class="special">&gt;</span><span class="identifier">Server</span><span class="special">.</span><span class="identifier">exe</span>
<span class="identifier">Press</span> <span class="identifier">Enter</span> <span class="identifier">to</span> <span class="identifier">exit</span><span class="special">...</span>
</pre>
<p>
        </p>
<p>
          , and then the client:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">c</span><span class="special">:\</span><span class="identifier">Projects</span><span class="special">\</span><span class="identifier">RcfSample</span><span class="special">\</span><span class="identifier">Debug</span><span class="special">&gt;</span><span class="identifier">Client</span><span class="special">.</span><span class="identifier">exe</span>
<span class="identifier">Calling</span> <span class="identifier">the</span> <span class="identifier">I_HelloWorld</span> <span class="identifier">Print</span><span class="special">()</span> <span class="identifier">method</span><span class="special">.</span>
<span class="identifier">c</span><span class="special">:\</span><span class="identifier">Projects</span><span class="special">\</span><span class="identifier">RcfSample</span><span class="special">\</span><span class="identifier">Debug</span><span class="special">&gt;</span>
</pre>
<p>
        </p>
<p>
          In the server window, you should now see:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">c</span><span class="special">:\</span><span class="identifier">Projects</span><span class="special">\</span><span class="identifier">RcfSample</span><span class="special">\</span><span class="identifier">Debug</span><span class="special">&gt;</span><span class="identifier">Server</span><span class="special">.</span><span class="identifier">exe</span>
<span class="identifier">Press</span> <span class="identifier">Enter</span> <span class="identifier">to</span> <span class="identifier">exit</span><span class="special">...</span>
<span class="identifier">I_HelloWorld</span> <span class="identifier">service</span><span class="special">:</span> <span class="identifier">Hello</span> <span class="identifier">World</span>
</pre>
<p>
        </p>
<p>
          To simplify the rest of the tutorial, we'll rewrite our Hello World example
          so that the client and server run in a single process:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>

<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RCF</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>


<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>

    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Calling the I_HelloWorld Print() method."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>

    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          Running this program yields the output:
        </p>
<pre class="programlisting">Calling the I_HelloWorld Print() method.
I_HelloWorld service: Hello World
</pre>
<p>
          The rest of the tutorial will build on this example, to illustrate some
          of the fundamental features of RCF.
        </p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.Interfaces"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.Interfaces" title="Interfaces and implementations"> Interfaces and implementations</a>
</h3></div></div></div>
<p>
        RCF allows you to define remote interfaces, directly in code. In the example
        above, we defined the <code class="computeroutput"><span class="identifier">I_HelloWorld</span></code>
        interface:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>
</pre>
<p>
      </p>
<p>
        <code class="computeroutput"><span class="identifier">RCF_BEGIN</span><span class="special">()</span></code>,
        <code class="computeroutput"><span class="identifier">RCF_METHOD_xx</span><span class="special">()</span></code>,
        and <code class="computeroutput"><span class="identifier">RCF_END</span><span class="special">()</span></code>
        are macros that are used to generate client and server stubs for remote calls.
      </p>
<div class="itemizedlist"><ul type="disc">
<li>
            <code class="computeroutput"><span class="identifier">RCF_BEGIN</span><span class="special">()</span></code>
            starts the interface definition, and defines the compile time identifier
            of the interface (<code class="computeroutput"><span class="identifier">I_HelloWorld</span></code>),
            and the runtime identifier of the interface (<code class="computeroutput"><span class="string">"I_HelloWorld"</span></code>).
          </li>
<li>
            <code class="computeroutput"><span class="identifier">RCF_METHOD_xx</span><span class="special">()</span></code>
            - The <code class="computeroutput"><span class="identifier">RCF_METHOD_xx</span><span class="special">()</span></code>
            macros define remote methods. <code class="computeroutput"><span class="identifier">RCF_METHOD_V1</span><span class="special">()</span></code> defines a remote method taking one
            parameter (in this case <code class="computeroutput"><span class="keyword">const</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span></code>),
            and returning <code class="computeroutput"><span class="keyword">void</span></code>. <code class="computeroutput"><span class="identifier">RCF_METHOD_R2</span><span class="special">()</span></code>
            defines a remote method with two parameters and a non-<code class="computeroutput"><span class="keyword">void</span></code>
            return value, and so on. The <code class="computeroutput"><span class="identifier">RCF_METHOD_xx</span><span class="special">()</span></code> macros are defined for <code class="computeroutput"><span class="keyword">void</span></code> and non-<code class="computeroutput"><span class="keyword">void</span></code>
            remote calls taking up to 15 parameters.
          </li>
<li>
            <code class="computeroutput"><span class="identifier">RCF_END</span><span class="special">()</span></code>
            ends the interface definition.
          </li>
</ul></div>
<p>
        On the server, we bind the interface to a servant object:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        Let's add a few more remote methods to the <code class="computeroutput"><span class="identifier">I_HelloWorld</span></code>
        interface. We'll add methods to print a list of strings, and return the number
        of characters printed:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Serialization code for std::vector&lt;&gt;.
</span><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">SF</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
    <span class="identifier">RCF_METHOD_R1</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span>  <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="special">&amp;)</span>
    <span class="identifier">RCF_METHOD_V2</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="special">&amp;,</span> <span class="keyword">int</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>
</pre>
<p>
      </p>
<p>
        Remote calls can return arguments either through a return value (as the second
        <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>
        method does), or through a non-const reference parameter (as the third <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>
        method does).
      </p>
<p>
        Having added these methods to the <code class="computeroutput"><span class="identifier">I_HelloWorld</span></code>
        interface, we also need to implement them in the <code class="computeroutput"><span class="identifier">HelloWorldImpl</span></code>
        servant object:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="keyword">int</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">v</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">int</span> <span class="identifier">howManyChars</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
        <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
            <span class="identifier">howManyChars</span> <span class="special">+=</span> <span class="identifier">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">].</span><span class="identifier">size</span><span class="special">();</span>
        <span class="special">}</span>
        <span class="keyword">return</span> <span class="identifier">howManyChars</span><span class="special">;</span>
    <span class="special">}</span>
    
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">v</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">&amp;</span> <span class="identifier">howManyChars</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">howManyChars</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
        <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
            <span class="identifier">howManyChars</span> <span class="special">+=</span> <span class="identifier">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">].</span><span class="identifier">size</span><span class="special">();</span>
        <span class="special">}</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        Notice that <code class="computeroutput"><span class="identifier">HelloWorldImpl</span></code>
        is not a derived class. Instead of virtual functions, RCF uses template-based
        static polymorphism to bind interfaces to implementations.
      </p>
<p>
        Here is sample client code to call the new <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code> methods:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">stringsToPrint</span><span class="special">;</span>
<span class="identifier">stringsToPrint</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"AAA"</span><span class="special">);</span>
<span class="identifier">stringsToPrint</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"BBB"</span><span class="special">);</span>
<span class="identifier">stringsToPrint</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="string">"CCC"</span><span class="special">);</span>

<span class="comment">// Remote call returning argument through return value.
</span><span class="keyword">int</span> <span class="identifier">howManyChars</span> <span class="special">=</span> <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="identifier">stringsToPrint</span><span class="special">);</span>

<span class="comment">// Remote call returning argument through non-const reference parameter.
</span><span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="identifier">stringsToPrint</span><span class="special">,</span> <span class="identifier">howManyChars</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        And the output:
      </p>
<pre class="programlisting">I_HelloWorld service: AAA
I_HelloWorld service: BBB
I_HelloWorld service: CCC
I_HelloWorld service: AAA
I_HelloWorld service: BBB
I_HelloWorld service: CCC
</pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.Errors"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.Errors" title="Error handling"> Error handling</a>
</h3></div></div></div>
<p>
        If a remote call does not complete, RCF will throw an exception containing
        an error message describing the error condition. Let's put a <code class="computeroutput"><span class="keyword">try</span><span class="special">/</span><span class="keyword">catch</span></code>
        wrapper around the remote call:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">try</span>
<span class="special">{</span>
    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">getErrorString</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        We can simulate the server being down, by commenting out the <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">start</span><span class="special">()</span></code>
        call:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
<span class="comment">//server.start();
</span></pre>
<p>
      </p>
<p>
        Running the client, we now get this:
      </p>
<pre class="programlisting">Error: Client connection to 127.0.0.1:50001 timed out after 2000 ms (server not started?).
</pre>
<p>
        All exceptions thrown by RCF are derived from <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span></code>.
        <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span></code> holds various descriptive and
        contextual information about the error. You can call <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span><span class="special">::</span><span class="identifier">getErrorId</span><span class="special">()</span></code> to retrieve the error code, and <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span><span class="special">::</span><span class="identifier">getErrorString</span><span class="special">()</span></code>, to retrieve an English translation of
        the error, including any error-specific arguments.
      </p>
<p>
        If the server implementation of a remote call throws an exception, it will
        be caught by the <code class="computeroutput"><span class="identifier">RcfServer</span></code>
        and returned to the client, where it is thrown as a <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RemoteException</span></code>.
        For example, if we start the server with the following servant implementation:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"Print() service is unavailable at this time."</span><span class="special">);</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        , the client will now output:
      </p>
<pre class="programlisting">Error: Server-side user exception. Exception type: class std::runtime_error. Exception message: "Print() service is unavailable at this time.".
</pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.ClientStubs"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.ClientStubs" title="Client stubs"> Client stubs</a>
</h3></div></div></div>
<p>
        Remote calls are always made through a client stub (<code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ClientStub</span></code>).
        You can access the client stub of a <code class="computeroutput"><span class="identifier">RcfClient</span><span class="special">&lt;&gt;</span></code> by calling <code class="computeroutput"><span class="identifier">RcfClient</span><span class="special">&lt;&gt;::</span><span class="identifier">getClientStub</span><span class="special">()</span></code>. The client stub contains a number of settings
        that affect how a remote call is executed.
      </p>
<p>
        Two of the most important settings are the connection timeout and the remote
        call timeout. The connection timeout determines how long RCF will wait while
        trying to establish a network connection to the server. The remote call timeout
        determines how long RCF will wait for a remote call response to return from
        the server.
      </p>
<p>
        To change these settings, call the <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setConnectionTimeoutMs</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setRemoteCallTimeoutMs</span><span class="special">()</span></code> functions:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// 5 second timeout when establishing network connection.
</span><span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setConnectTimeoutMs</span><span class="special">(</span><span class="number">5</span><span class="special">*</span><span class="number">1000</span><span class="special">);</span>

<span class="comment">// 60 second timeout when waiting for remote call response from the server.
</span><span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setRemoteCallTimeoutMs</span><span class="special">(</span><span class="number">60</span><span class="special">*</span><span class="number">1000</span><span class="special">);</span>

<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        See <a class="link" href="Clientside.html" title="Remote Calls - Client-side">Remote calls - Client-side</a>
        for more about client stubs.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.server_sessions"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.server_sessions" title="Server sessions">Server sessions</a>
</h3></div></div></div>
<p>
        On the server-side, RCF maintains a session (<code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfSession</span></code>)
        for every client connection to the server. The <code class="computeroutput"><span class="identifier">RcfSession</span></code>
        of a client connection is available to server-side code through <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">getCurrentSession</span><span class="special">()</span></code>. You can use <code class="computeroutput"><span class="identifier">RcfSession</span></code>
        to maintain application data specific to a particular client connection.
        Arbitrary C++ objects can be stored in a session by calling <code class="computeroutput"><span class="identifier">RcfSession</span><span class="special">::</span><span class="identifier">createSessionObject</span><span class="special">&lt;&gt;()</span></code>
        or <code class="computeroutput"><span class="identifier">RcfSession</span><span class="special">::</span><span class="identifier">getSessionObject</span><span class="special">&lt;&gt;()</span></code>.
      </p>
<p>
        For instance, to associate a <code class="computeroutput"><span class="identifier">HelloWorldSession</span></code>
        object with each client connection to the <code class="computeroutput"><span class="identifier">I_HelloWorld</span></code>
        interface, which tracks the numer of calls made on a connection:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">HelloWorldSession</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="identifier">HelloWorldSession</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">mCallCount</span><span class="special">(</span><span class="number">0</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Created HelloWorldSession object."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="special">~</span><span class="identifier">HelloWorldSession</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Destroyed HelloWorldSession object."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">mCallCount</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfSession</span> <span class="special">&amp;</span> <span class="identifier">session</span> <span class="special">=</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">getCurrentRcfSession</span><span class="special">();</span>

        <span class="comment">// Creates the session object if it doesn't already exist.
</span>        <span class="identifier">HelloWorldSession</span> <span class="special">&amp;</span> <span class="identifier">hwSession</span> <span class="special">=</span> <span class="identifier">session</span><span class="special">.</span><span class="identifier">getSessionObject</span><span class="special">&lt;</span><span class="identifier">HelloWorldSession</span><span class="special">&gt;(</span><span class="keyword">true</span><span class="special">);</span>

        <span class="special">++</span><span class="identifier">hwSession</span><span class="special">.</span><span class="identifier">mCallCount</span><span class="special">;</span>

        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="string">"Total calls on this connection so far: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">hwSession</span><span class="special">.</span><span class="identifier">mCallCount</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        Distinct <code class="computeroutput"><span class="identifier">RcfClient</span><span class="special">&lt;&gt;</span></code>
        instances will have distinct connections to the server. Here we are calling
        <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>
        three times from two <code class="computeroutput"><span class="identifier">RcfClient</span><span class="special">&lt;&gt;</span></code> instances:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="number">2</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>

<span class="comment">// Wait a little so the server has time to destroy the last session.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">sleepMs</span><span class="special">(</span><span class="number">1000</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        , resulting in the following output:
      </p>
<pre class="programlisting">Created HelloWorldSession object.
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 1
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 2
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 3
Destroyed HelloWorldSession object.
Created HelloWorldSession object.
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 1
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 2
I_HelloWorld service: Hello World
I_HelloWorld service: Total calls on this connection so far: 3
Destroyed HelloWorldSession object.
</pre>
<p>
        The server session and any associated session objects are destroyed when
        the client connection is closed.
      </p>
<p>
        See <a class="link" href="Serverside.html" title="Remote Calls - Server-side">Remote calls - Server-side</a>
        for more about server sessions.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.Transports"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.Transports" title="Transports"> Transports</a>
</h3></div></div></div>
<p>
        RCF makes it easy to change the underlying transport of a remote call. The
        transport layer is determined by the endpoint parameters passed to <code class="computeroutput"><span class="identifier">RcfServer</span></code> and <code class="computeroutput"><span class="identifier">RcfClient</span><span class="special">&lt;&gt;</span></code>. So far we've been using <code class="computeroutput"><span class="identifier">TcpEndpoint</span></code>, to specify a TCP transport.
      </p>
<p>
        By default, when you specify a <code class="computeroutput"><span class="identifier">TcpEndpoint</span></code>
        with only a port number, RCF will use <code class="computeroutput"><span class="number">127.0</span><span class="special">.</span><span class="number">0.1</span></code> as the
        IP address. So the following two snippets are equivalent:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"127.0.0.1"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        , as are the following:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"127.0.0.1"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        <code class="computeroutput"><span class="number">127.0</span><span class="special">.</span><span class="number">0.1</span></code> is the IPv4 loopback address. A server
        listening on <code class="computeroutput"><span class="number">127.0</span><span class="special">.</span><span class="number">0.1</span></code> will only be available to clients on the
        same machine as the server. It's likely you'll want to run clients across
        the network, in which case the server will need to listen on an externally
        visible network address. The easiest way to do that is to specify <code class="computeroutput"><span class="number">0.0</span><span class="special">.</span><span class="number">0.0</span></code>
        (for IPv4), or <code class="computeroutput"><span class="special">::</span><span class="number">0</span></code>
        (for IPv6) instead, which will make the server listen on all available network
        interfaces:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"0.0.0.0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// Client-side.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"Server123"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        RCF supports a number of other endpoint types as well. To run the server
        and client over UDP, use <code class="computeroutput"><span class="identifier">UdpEndpoint</span></code>:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">UdpEndpoint</span><span class="special">(</span><span class="string">"0.0.0.0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// Client-side.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">UdpEndpoint</span><span class="special">(</span><span class="string">"Server123"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        To run the server and client over named pipes, use <code class="computeroutput"><span class="identifier">NamedPipeEndpoint</span></code>:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Win32NamedPipeEndpoint</span><span class="special">(</span><span class="string">"MyPipe"</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// Client-side.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Win32NamedPipeEndpoint</span><span class="special">(</span><span class="string">"MyPipe"</span><span class="special">)</span> <span class="special">);</span>
</pre>
<p>
      </p>
<p>
        <code class="computeroutput"><span class="identifier">NamedPipeEndpoint</span></code> maps onto
        <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365590(v=vs.85).aspx" target="_top">Windows
        named pipes</a> on Windows systems, and <a href="http://en.wikipedia.org/wiki/Unix_domain_socket" target="_top">UNIX
        local domain sockets</a> on UNIX-based systems.
      </p>
<p>
        It's usually not practical to use UDP for two-way (request/response) messaging,
        as the unreliable semantics of UDP mean that messages may not be delivered,
        or may be delivered out of order. UDP is useful in one-way messaging scenarios,
        where the server application logic is resilient to messages being lost or
        arriving out of order.
      </p>
<p>
        RCF supports tunneling of remote calls over the HTTP and HTTPS protocols.
        <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpEndpoint</span></code> is used to configure tunneling
        over HTTP. Here is an example of a client making remote calls to a server,
        through a third party HTTP proxy:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side.
</span><span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorldImpl</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpEndpoint</span><span class="special">(</span><span class="string">"0.0.0.0"</span><span class="special">,</span> <span class="number">80</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorldImpl</span><span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="comment">// Client-side.
</span><span class="comment">// This client will connect to server1.acme.com via the HTTP proxy at proxy.acme.com:8080.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpEndpoint</span><span class="special">(</span><span class="string">"server1.acme.com"</span><span class="special">,</span> <span class="number">80</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxy</span><span class="special">(</span><span class="string">"proxy.acme.com"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxyPort</span><span class="special">(</span><span class="number">8080</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        Similarly, <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpsEndpoint</span></code> can be used to configure
        tunneling over HTTPS:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side.
</span><span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorldImpl</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpsEndpoint</span><span class="special">(</span><span class="string">"0.0.0.0"</span><span class="special">,</span> <span class="number">443</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorldImpl</span><span class="special">);</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">CertificatePtr</span> <span class="identifier">serverCertPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">PfxCertificate</span><span class="special">(</span><span class="string">"path/to/certificate.p12"</span><span class="special">,</span> <span class="string">"password"</span><span class="special">,</span> <span class="string">"CertificateName"</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">setCertificate</span><span class="special">(</span><span class="identifier">serverCertPtr</span><span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="comment">// Client-side.
</span><span class="comment">// This client will connect to server1.acme.com via the HTTP proxy at proxy.acme.com:8080.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpsEndpoint</span><span class="special">(</span><span class="string">"server1.acme.com"</span><span class="special">,</span> <span class="number">443</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxy</span><span class="special">(</span><span class="string">"proxy.acme.com"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxyPort</span><span class="special">(</span><span class="number">8080</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        Certificates and certificate validation for HTTPS are configured as for the
        SSL transport protocol (see <a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.TransportProtocols" title="Transport protocols">Transport
        Protocols</a> below).
      </p>
<p>
        Multiple transports can be configured for a single <code class="computeroutput"><span class="identifier">RcfServer</span></code>.
        For example, to configure a server that accepts both IPv4 and IPv6 connections
        on port 50001:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">;</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"0.0.0.0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"::0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        On some platforms, the underlying network stack will allow you to specify
        <code class="computeroutput"><span class="special">::</span><span class="number">0</span></code>
        to listen on both IPv4 and IPv6 interfaces, in which case this would be sufficient:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">;</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"::0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        Here is a server accepting connections over TCP, UDP and named pipes:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">;</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="string">"::0"</span><span class="special">,</span> <span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">UdpEndpoint</span><span class="special">(</span><span class="string">"::0"</span><span class="special">,</span> <span class="number">50002</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Win32NamedPipeEndpoint</span><span class="special">(</span><span class="string">"MyPipe"</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        See <a class="link" href="Transports.html" title="Transports">Transports</a> for more
        information on transports.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.TransportProtocols"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.TransportProtocols" title="Transport protocols"> Transport
      protocols</a>
</h3></div></div></div>
<p>
        Transport protocols are layered on top of the transport, and provide authentication
        and encryption.
      </p>
<p>
        RCF supports the following transport protocols:
      </p>
<div class="itemizedlist"><ul type="disc">
<li>
            <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749(v=vs.85).aspx" target="_top">NTLM</a>
          </li>
<li>
            <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378747(v=vs.85).aspx" target="_top">Kerberos</a>
          </li>
<li>
            <a href="http://en.wikipedia.org/wiki/Secure_Socket_Layer" target="_top">SSL</a>
          </li>
</ul></div>
<p>
        The NTLM and Kerberos transport protocols are only supported on Windows,
        while the SSL transport protocol is supported on all platforms.
      </p>
<p>
        An <code class="computeroutput"><span class="identifier">RcfServer</span></code> can be configured
        to require certain transport protocols:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TransportProtocol</span><span class="special">&gt;</span> <span class="identifier">protocols</span><span class="special">;</span>
<span class="identifier">protocols</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ntlm</span><span class="special">);</span>
<span class="identifier">protocols</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Kerberos</span><span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">setSupportedTransportProtocols</span><span class="special">(</span><span class="identifier">protocols</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        On the client-side, <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setTransportProtocol</span><span class="special">()</span></code> is used to configure transport protocols.
        For instance, to use the NTLM protocol on a client connection:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setTransportProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ntlm</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        In this example, the client will authenticate itself to the server and encrypt
        its connection using the NTLM protocol, using the implicit credentials of
        the logged on user.
      </p>
<p>
        To provide explicit credentials, use <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setUsername</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setPassword</span><span class="special">()</span></code>:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setTransportProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ntlm</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setUsername</span><span class="special">(</span><span class="string">"SomeDomain\\Joe"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setPassword</span><span class="special">(</span><span class="string">"JoesPassword"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        The Kerberos protocol can be configured similarly. The Kerberos protocol
        requires the client to supply the Service Principal Name (SPN) of the server.
        You can do this by calling <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setKerberosSpn</span><span class="special">()</span></code>:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setTransportProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Kerberos</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setKerberosSpn</span><span class="special">(</span><span class="string">"SomeDomain\\ServerAccount"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        If a client attempts to call <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code> without configuring one of the transport
        protocols required by the server, they will get an error:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">try</span>
<span class="special">{</span>
    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">getErrorString</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<pre class="programlisting">Error: Server requires one of the following transport protocols to be used: NTLM, Kerberos.
</pre>
<p>
        From within the server implementation of <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>, you can retrieve the transport protocol
        of the current session. If the transport protocol is NTLM or Kerberos, you
        can also retrieve the username of the client, as well as impersonate the
        client:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfSession</span> <span class="special">&amp;</span> <span class="identifier">session</span> <span class="special">=</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">getCurrentRcfSession</span><span class="special">();</span>

        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TransportProtocol</span> <span class="identifier">protocol</span> <span class="special">=</span> <span class="identifier">session</span><span class="special">.</span><span class="identifier">getTransportProtocol</span><span class="special">();</span>

        <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">protocol</span> <span class="special">==</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ntlm</span> <span class="special">||</span> <span class="identifier">protocol</span> <span class="special">==</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Kerberos</span> <span class="special">)</span>
        <span class="special">{</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">clientUsername</span> <span class="special">=</span> <span class="identifier">session</span><span class="special">.</span><span class="identifier">getClientUsername</span><span class="special">();</span>

            <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">SspiImpersonator</span> <span class="identifier">impersonator</span><span class="special">(</span><span class="identifier">session</span><span class="special">);</span>

            <span class="comment">// Now running under Windows credentials of client.
</span>            <span class="comment">// ...
</span>
            <span class="comment">// Impersonation ends when we exit scope.
</span>        <span class="special">}</span>

        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        RCF also supports using SSL as the transport protocol. RCF provides two SSL
        implementations, one based on OpenSSL, and the other based on the Windows
        Schannel security package. The Windows Schannel implementation is used automatically
        on Windows, while the OpenSSL implementation is used if <code class="computeroutput"><span class="identifier">RCF_USE_OPENSSL</span></code>
        is defined when building RCF (see <a class="link" href="AppendixBuilding.html" title="Appendix - Building RCF">Building</a>).
      </p>
<p>
        SSL-enabled servers need to configure a SSL certificate. The mechanics of
        certificate configuration vary depending on which implementation is being
        used. Here is an example using the Schannel SSL implementation:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">CertificatePtr</span> <span class="identifier">serverCertificatePtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">PfxCertificate</span><span class="special">(</span>
    <span class="string">"C:\\ServerCert.p12"</span><span class="special">,</span> 
    <span class="string">"Password"</span><span class="special">,</span>
    <span class="string">"CertificateName"</span><span class="special">)</span> <span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">setCertificate</span><span class="special">(</span><span class="identifier">serverCertificatePtr</span><span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setTransportProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ssl</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setEnableSchannelCertificateValidation</span><span class="special">(</span><span class="string">"localhost"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">PfxCertificate</span></code> is used to load PKCS #12
        certificates, from .pfx and .p12 files. RCF also provides the <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">StoreCertificate</span></code>
        class, to load certificates from a Windows certificate store.
      </p>
<p>
        When using the OpenSSL-based SSL implementation, the <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">PemCertificate</span></code>
        class is used to load PEM certificates, from .pem files.
      </p>
<p>
        RCF also supports link level compression of remote calls. Compression is
        configured independently of transport protocols, using <code class="computeroutput"><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">setEnableCompression</span><span class="special">()</span></code>. The compression stage is applied immediately
        before the transport protocol stage.
      </p>
<p>
        Here is an example of a client connecting to a server through an HTTP proxy,
        using NTLM for authentication and encryption, and with compression enabled:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpEndpoint</span><span class="special">(</span><span class="string">"server123.com"</span><span class="special">,</span> <span class="number">80</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxy</span><span class="special">(</span><span class="string">"proxy.mycompany.com"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setHttpProxyPort</span><span class="special">(</span><span class="number">8080</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setTransportProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Tp_Ntlm</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">setEnableCompression</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>

<span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        For more information see <a class="link" href="TransportProtocols.html" title="Transport Protocols">Transport
        protocols</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.Threading"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.Threading" title="Server-side threading"> Server-side threading</a>
</h3></div></div></div>
<p>
        By default a <code class="computeroutput"><span class="identifier">RcfServer</span></code> uses
        a single thread to handle incoming remote calls, so remote calls are dispatched
        serially, one after the other.
      </p>
<p>
        This can be a problem if you have multiple clients and some of them are making
        calls that take significant time to complete. To improve responsiveness in
        these situations, a <code class="computeroutput"><span class="identifier">RcfServer</span></code>
        can be configured to run multiple threads and dispatch remote calls in parallel.
      </p>
<p>
        To configure a multi-threaded <code class="computeroutput"><span class="identifier">RcfServer</span></code>,
        use <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">setThreadPool</span><span class="special">()</span></code>
        to assign a thread pool to the server. RCF thread pools can be configured
        to use either a fixed number of threads:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// Thread pool with fixed number of threads (5).
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPoolPtr</span> <span class="identifier">tpPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPool</span><span class="special">(</span><span class="number">5</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">setThreadPool</span><span class="special">(</span><span class="identifier">tpPtr</span><span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        , or a dynamic number of threads, varying with server load:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="comment">// Thread pool with varying number of threads (1 to 25).
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPoolPtr</span> <span class="identifier">tpPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPool</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">25</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">setThreadPool</span><span class="special">(</span><span class="identifier">tpPtr</span><span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        Thread pools configured through <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">setThreadPool</span><span class="special">()</span></code> are shared across all the transports of
        that <code class="computeroutput"><span class="identifier">RcfServer</span></code>. It is also
        possible to use <code class="computeroutput"><span class="identifier">I_ServerTransport</span><span class="special">::</span><span class="identifier">setThreadPool</span><span class="special">()</span></code> to configure thread pools for individual
        transports:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">;</span>

<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ServerTransport</span> <span class="special">&amp;</span> <span class="identifier">tcpTransport</span> <span class="special">=</span> <span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">));</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ServerTransport</span> <span class="special">&amp;</span> <span class="identifier">pipeTransport</span> <span class="special">=</span> <span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Win32NamedPipeEndpoint</span><span class="special">(</span><span class="string">"MyPipe"</span><span class="special">));</span>

<span class="comment">// Thread pool with up to 5 threads to serve TCP clients.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPoolPtr</span> <span class="identifier">tcpThreadPoolPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPool</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">tcpTransport</span><span class="special">.</span><span class="identifier">setThreadPool</span><span class="special">(</span><span class="identifier">tcpThreadPoolPtr</span><span class="special">);</span>

<span class="comment">// Thread pool with single thread to serve named pipe clients.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPoolPtr</span> <span class="identifier">pipeThreadPoolPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPool</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">pipeTransport</span><span class="special">.</span><span class="identifier">setThreadPool</span><span class="special">(</span><span class="identifier">pipeThreadPoolPtr</span><span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.asynchronous_remote_calls"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls" title="Asynchronous remote calls">Asynchronous
      remote calls</a>
</h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_invocation">Asynchronous
        remote call invocation</a></span></dt>
<dt><span class="section"><a href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_dispatching">Asynchronous
        remote call dispatching</a></span></dt>
</dl></div>
<p>
        RCF supports client-side asynchronous remote call invocation, and server-side
        asynchronous remote call dispatching.
      </p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_invocation"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_invocation" title="Asynchronous remote call invocation">Asynchronous
        remote call invocation</a>
</h4></div></div></div>
<p>
          On the client-side, asynchronous remote calls allow you to avoid blocking
          the thread that is making a remote call. Asynchronous remote calls complete
          on background threads, and the calling thread is notified at a later point,
          when the call completes.
        </p>
<p>
          Asynchronous remote call invocation is implemented in RCF using the <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;&gt;</span></code>
          template. Here is a simple example of waiting for an asynchronous call
          to complete:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fRet</span><span class="special">;</span>

<span class="comment">// Asynchronous remote call.
</span><span class="identifier">fRet</span> <span class="special">=</span> <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>

<span class="comment">// Wait for the call to complete.
</span><span class="keyword">while</span> <span class="special">(!</span><span class="identifier">fRet</span><span class="special">.</span><span class="identifier">ready</span><span class="special">())</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">sleepMs</span><span class="special">(</span><span class="number">1000</span><span class="special">);</span>

<span class="comment">// Check for errors.
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Exception</span><span class="special">&gt;</span> <span class="identifier">ePtr</span> <span class="special">=</span> <span class="identifier">client</span><span class="special">.</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">getAsyncException</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">ePtr</span><span class="special">.</span><span class="identifier">get</span><span class="special">())</span>
<span class="special">{</span>
    <span class="comment">// Error handling.
</span>    <span class="comment">// ...
</span><span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">howManyCharsPrinted</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">fRet</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          A remote call is performed asynchronously, if any of the parameters, or
          the return value, is of type <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;&gt;</span></code>, or if <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">AsyncOneway</span></code>
          or <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">AsyncTwoway</span></code> is specified as the calling
          semantic. Once a call is complete, <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;&gt;</span></code> instances can be dereferenced to
          retrieve the return values. If the call completed with an error, the error
          can be retrieved by calling <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ClientStub</span><span class="special">::</span><span class="identifier">getAsyncException</span><span class="special">()</span></code> . The error will also be thrown if an
          attempt is made to dereference an associated <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;&gt;</span></code> instance.
        </p>
<p>
          Instead of waiting for the result on the calling thread, we can assign
          a completion callback to the remote call:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">HelloWorldPtr</span><span class="special">;</span>

<span class="keyword">void</span> <span class="identifier">onPrintCompleted</span><span class="special">(</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fRet</span><span class="special">,</span> 
    <span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">howManyCharsPrinted</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">fRet</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">(</span>
    <span class="keyword">new</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">))</span> <span class="special">);</span>

<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fRet</span><span class="special">;</span>

<span class="comment">// Asynchronous remote call, with completion callback.
</span><span class="identifier">fRet</span> <span class="special">=</span> <span class="identifier">clientPtr</span><span class="special">-&gt;</span><span class="identifier">Print</span><span class="special">(</span> 
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">AsyncTwoway</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">onPrintCompleted</span><span class="special">,</span> <span class="identifier">fRet</span><span class="special">,</span> <span class="identifier">clientPtr</span><span class="special">)</span> <span class="special">),</span> 
    <span class="string">"Hello World"</span><span class="special">);</span>
</pre>
<p>
        </p>
<p>
          We've passed both the <code class="computeroutput"><span class="identifier">Future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> return value and a reference counted
          client (<code class="computeroutput"><span class="identifier">HelloWorldPtr</span></code>)
          to the callback. If we were to destroy the client on the main thread, the
          asynchronous call would be automatically canceled, and the callback would
          not be called at all.
        </p>
<p>
          Asynchronous remote calls are useful in many circumstances. For instance,
          the following code will call <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code> once every 10 seconds on 50 different
          servers:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">onPrintCompleted</span><span class="special">(</span><span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">onWaitCompleted</span><span class="special">(</span><span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">);</span>

<span class="keyword">void</span> <span class="identifier">onPrintCompleted</span><span class="special">(</span><span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// Print() call completed. Wait for 10 seconds.
</span>
    <span class="identifier">clientPtr</span><span class="special">-&gt;</span><span class="identifier">getClientStub</span><span class="special">().</span><span class="identifier">wait</span><span class="special">(</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">onWaitCompleted</span><span class="special">,</span> <span class="identifier">clientPtr</span><span class="special">),</span>
        <span class="number">10</span><span class="special">*</span><span class="number">1000</span><span class="special">);</span>
<span class="special">}</span>

<span class="keyword">void</span> <span class="identifier">onWaitCompleted</span><span class="special">(</span><span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// 10 second wait completed. Make another Print() call.
</span>
    <span class="identifier">clientPtr</span><span class="special">-&gt;</span><span class="identifier">Print</span><span class="special">(</span> 
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">AsyncTwoway</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">onPrintCompleted</span><span class="special">,</span> <span class="identifier">clientPtr</span><span class="special">)),</span> 
        <span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="comment">// Addresses to 50 servers.
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">&gt;</span> <span class="identifier">servers</span><span class="special">(</span><span class="number">50</span><span class="special">);</span>
<span class="comment">// ...
</span>
<span class="comment">// Create a connection to each server, and make the first call.
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">HelloWorldPtr</span><span class="special">&gt;</span> <span class="identifier">clients</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="number">50</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">servers</span><span class="special">[</span><span class="identifier">i</span><span class="special">])</span> <span class="special">);</span>
    <span class="identifier">clients</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">clientPtr</span><span class="special">);</span>

    <span class="comment">// Asynchronous remote call, with completion callback.
</span>    <span class="identifier">clientPtr</span><span class="special">-&gt;</span><span class="identifier">Print</span><span class="special">(</span> 
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">AsyncTwoway</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">onPrintCompleted</span><span class="special">,</span> <span class="identifier">clientPtr</span><span class="special">)),</span> 
        <span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>

<span class="comment">// All 50 servers are now being called once every 10 s.
</span><span class="comment">// ...
</span>
<span class="comment">// Upon leaving scope, the clients are all automatically destroyed. Any
</span><span class="comment">// remote calls in progress are automatically canceled.
</span></pre>
<p>
        </p>
<p>
          Instead of blocking 50 threads with synchronous remote calls, all 50 connections
          are managed by a single thread. The remote call sequences to the 50 servers
          are all handled on a background RCF thread, and the connections are automatically
          destroyed when the main thread leaves scope.
        </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_dispatching"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.asynchronous_remote_calls.asynchronous_remote_call_dispatching" title="Asynchronous remote call dispatching">Asynchronous
        remote call dispatching</a>
</h4></div></div></div>
<p>
          RCF also supports server-side asynchronous remote call dispatching. When
          a remote call arrives at a <code class="computeroutput"><span class="identifier">RcfServer</span></code>,
          it is handled by one of the threads in the servers thread pool. To process
          the call asynchronously on another thread, you can use the <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RemoteCallContext</span><span class="special">&lt;&gt;</span></code>
          template to capture the server-side context of the remote call, and queue
          it for later processing.
        </p>
<p>
          Here is an example of using <code class="computeroutput"><span class="identifier">RemoteCallContext</span><span class="special">&lt;&gt;</span></code> in server-side code. Instead of
          responding to <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>
          calls in <code class="computeroutput"><span class="identifier">HelloWorldImpl</span><span class="special">::</span><span class="identifier">Print</span><span class="special">()</span></code>, we are passing the remote call contexts
          to a background thread to be processed in bulk once every second. The background
          thread uses <code class="computeroutput"><span class="identifier">RemoteCallContext</span><span class="special">::</span><span class="identifier">parameters</span><span class="special">()</span></code> to access the parameters of each remote
          call, and <code class="computeroutput"><span class="identifier">RemoteCallContext</span><span class="special">::</span><span class="identifier">commit</span><span class="special">()</span></code> to send the remote call response back
          to the client.
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">RCF</span><span class="special">/</span><span class="identifier">RemoteCallContext</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_R1</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="comment">// I_HelloWorld servant object
</span><span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>

    <span class="keyword">typedef</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RemoteCallContext</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;&gt;</span> <span class="identifier">PrintCall</span><span class="special">;</span>

    <span class="keyword">int</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="comment">// Capture the remote call context and queue it in mPrintCalls.
</span>        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Lock</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mPrintCallsMutex</span><span class="special">);</span>
        <span class="identifier">mPrintCalls</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">PrintCall</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">getCurrentRcfSession</span><span class="special">())</span> <span class="special">);</span>

        <span class="comment">// Dummy return value.
</span>        <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="identifier">HelloWorldImpl</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="comment">// Start the asynchronous printing thread.
</span>        <span class="identifier">mStopFlag</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>

        <span class="identifier">mPrintThreadPtr</span><span class="special">.</span><span class="identifier">reset</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Thread</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
            <span class="special">&amp;</span><span class="identifier">HelloWorldImpl</span><span class="special">::</span><span class="identifier">processPrintCalls</span><span class="special">,</span> 
            <span class="keyword">this</span><span class="special">)</span> <span class="special">)</span> <span class="special">);</span>
    <span class="special">}</span>

    <span class="special">~</span><span class="identifier">HelloWorldImpl</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="comment">// Stop the asynchronous printing thread.
</span>        <span class="identifier">mStopFlag</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
        <span class="identifier">mPrintThreadPtr</span><span class="special">-&gt;</span><span class="identifier">join</span><span class="special">();</span>
    <span class="special">}</span>

<span class="keyword">private</span><span class="special">:</span>

    <span class="comment">// Queue of remote calls.
</span>    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Mutex</span>              <span class="identifier">mPrintCallsMutex</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">PrintCall</span><span class="special">&gt;</span>   <span class="identifier">mPrintCalls</span><span class="special">;</span>

    <span class="comment">// Asynchronous printing thread.
</span>    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ThreadPtr</span>          <span class="identifier">mPrintThreadPtr</span><span class="special">;</span>
    <span class="keyword">volatile</span> <span class="keyword">bool</span>           <span class="identifier">mStopFlag</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">processPrintCalls</span><span class="special">()</span>
    <span class="special">{</span>
        <span class="comment">// Once a second, process all queued Print() calls.
</span>        <span class="keyword">while</span> <span class="special">(!</span><span class="identifier">mStopFlag</span><span class="special">)</span>
        <span class="special">{</span>
            <span class="identifier">Sleep</span><span class="special">(</span><span class="number">1000</span><span class="special">);</span>

            <span class="comment">// Retrieve all queued print calls.
</span>            <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">PrintCall</span><span class="special">&gt;</span> <span class="identifier">printCalls</span><span class="special">;</span>
            <span class="special">{</span>
                <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Lock</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mPrintCallsMutex</span><span class="special">);</span>
                <span class="identifier">printCalls</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">mPrintCalls</span><span class="special">);</span>
            <span class="special">}</span>

            <span class="comment">// Process them.
</span>            <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="identifier">printCalls</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
            <span class="special">{</span>
                <span class="identifier">PrintCall</span> <span class="special">&amp;</span> <span class="identifier">printCall</span> <span class="special">=</span> <span class="identifier">printCalls</span><span class="special">[</span><span class="identifier">i</span><span class="special">];</span>
                <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">stringToPrint</span> <span class="special">=</span> <span class="identifier">printCall</span><span class="special">.</span><span class="identifier">parameters</span><span class="special">().</span><span class="identifier">a1</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
                <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">stringToPrint</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
                <span class="identifier">printCall</span><span class="special">.</span><span class="identifier">parameters</span><span class="special">().</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span> <span class="identifier">stringToPrint</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">);</span>
                <span class="identifier">printCall</span><span class="special">.</span><span class="identifier">commit</span><span class="special">();</span>
            <span class="special">}</span>
        <span class="special">}</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
        </p>
<p>
          The client code is unchanged:
        </p>
<p>
          
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="keyword">int</span> <span class="identifier">charsPrinted</span> <span class="special">=</span> <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        </p>
</div>
<p>
        For more information, see <a class="link" href="AsyncRemoteCalls.html" title="Asynchronous Remote Calls">Asynchronous
        Remote Calls</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.PubSub"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.PubSub" title="Publish/subscribe"> Publish/subscribe</a>
</h3></div></div></div>
<p>
        RCF makes it easy to setup publish/subscribe feeds. For example, here is
        a publisher publishing <code class="computeroutput"><span class="string">"Hello World"</span></code>
        once every second:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">publishingServer</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">publishingServer</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="comment">// Start publishing.
</span><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Publisher</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">HelloWorldPublisherPtr</span><span class="special">;</span>
<span class="identifier">HelloWorldPublisherPtr</span> <span class="identifier">pubPtr</span> <span class="special">=</span> <span class="identifier">publishingServer</span><span class="special">.</span><span class="identifier">createPublisher</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;();</span>

<span class="keyword">while</span> <span class="special">(</span><span class="identifier">shouldContinue</span><span class="special">())</span>
<span class="special">{</span>
    <span class="identifier">Sleep</span><span class="special">(</span><span class="number">1000</span><span class="special">);</span>

    <span class="comment">// Publish a Print() call to all currently connected subscribers.
</span>    <span class="identifier">pubPtr</span><span class="special">-&gt;</span><span class="identifier">publish</span><span class="special">().</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
<span class="special">}</span>

<span class="comment">// Close the publisher.
</span><span class="identifier">pubPtr</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        To create a subscription to the publisher:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Start a subscriber.
</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">subscriptionServer</span><span class="special">((</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">()</span> <span class="special">));</span>
<span class="identifier">subscriptionServer</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

<span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>

<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">SubscriptionPtr</span> <span class="identifier">subPtr</span> <span class="special">=</span> <span class="identifier">subscriptionServer</span><span class="special">.</span><span class="identifier">createSubscription</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span>
    <span class="identifier">helloWorld</span><span class="special">,</span> 
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">));</span>

<span class="comment">// At this point Print() will be called on the helloWorld object once a second.
</span><span class="comment">// ...
</span>
<span class="comment">// Close the subscription.
</span><span class="identifier">subPtr</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        Each call the publisher makes is sent as a oneway call to all subscribers.
      </p>
<p>
        For more information on publish/subscribe messaging, see <a class="link" href="PubSub.html" title="Publish/Subscribe">Publish/subscribe</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.callback_connections"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.callback_connections" title="Callback connections">Callback
      connections</a>
</h3></div></div></div>
<p>
        So far we've seen clients making remote calls to servers. It's also possible
        for a server to make remote calls back to a client, once the client has established
        a connection. To do this, the client starts a <code class="computeroutput"><span class="identifier">RcfServer</span></code>
        of its own, and calls <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">createCallbackConnection</span><span class="special">()</span></code>:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Client-side
</span><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>
        
    <span class="comment">// Client needs a RcfServer to accept callback connections.
</span>    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">callbackServer</span><span class="special">((</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">()</span> <span class="special">));</span>
    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">callbackServer</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
    <span class="identifier">callbackServer</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="comment">// Establish client connection to server.
</span>    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

    <span class="comment">// Create the callback connection.
</span>    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">createCallbackConnection</span><span class="special">(</span><span class="identifier">client</span><span class="special">,</span> <span class="identifier">callbackServer</span><span class="special">);</span>

    <span class="comment">// Server can now call Print() on the helloWorld object.
</span>    <span class="comment">// ...
</span>        
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        On the server-side, <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">setCallbackConnectionCb</span><span class="special">()</span></code> is used to take control over the callback
        connection once it has been created by the client:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Server-side
</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="special">&gt;</span>    <span class="identifier">HelloWorldPtr</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Mutex</span>                                              <span class="identifier">gCallbackClientsMutex</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">HelloWorldPtr</span> <span class="special">&gt;</span>                            <span class="identifier">gCallbackClients</span><span class="special">;</span>

<span class="keyword">void</span> <span class="identifier">onCallbackConnectionCreated</span><span class="special">(</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfSessionPtr</span> <span class="identifier">sessionPtr</span><span class="special">,</span> 
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">ClientTransportAutoPtr</span> <span class="identifier">transportAutoPtr</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">HelloWorldPtr</span><span class="special">;</span>
    <span class="identifier">HelloWorldPtr</span> <span class="identifier">helloWorldPtr</span><span class="special">(</span> <span class="keyword">new</span> <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">transportAutoPtr</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Lock</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">gCallbackClientsMutex</span><span class="special">);</span>
    <span class="identifier">gCallbackClients</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">helloWorldPtr</span> <span class="special">);</span>
<span class="special">}</span>


<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">setOnCallbackConnectionCreated</span><span class="special">(</span> 
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">onCallbackConnectionCreated</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_2</span><span class="special">)</span> <span class="special">);</span>

    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="comment">// Wait for clients to create callback connections.
</span>    <span class="comment">// ...
</span>    
    <span class="comment">// Retrieve all created callback connections.
</span>    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">HelloWorldPtr</span><span class="special">&gt;</span> <span class="identifier">clients</span><span class="special">;</span>
    <span class="special">{</span>
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Lock</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">gCallbackClientsMutex</span><span class="special">);</span>
        <span class="identifier">clients</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">gCallbackClients</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="comment">// Call Print() on them.
</span>    <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="identifier">clients</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">HelloWorldPtr</span> <span class="identifier">clientPtr</span> <span class="special">=</span> <span class="identifier">clients</span><span class="special">[</span><span class="identifier">i</span><span class="special">];</span>
        <span class="identifier">clientPtr</span><span class="special">-&gt;</span><span class="identifier">Print</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        Callback connections function just like regular connections, with the exception
        that callback connections cannot be reconnected. If a callback connection
        is lost, the client will need to connect again and call <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">createCallbackConnection</span><span class="special">()</span></code>, to re-establish connectivity.
      </p>
<p>
        For more information on callback connections, see <a class="link" href="CallbackConn.html" title="Callback Connections">Callback
        Connections</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.file_transfers"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.file_transfers" title="File transfers">File transfers</a>
</h3></div></div></div>
<p>
        File downloads and uploads are common in distributed systems. RCF provides
        built-in support for file transfers, through the <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span></code>
        and <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileUpload</span></code> classes. <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span></code>
        and <code class="computeroutput"><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileUpload</span></code> are used as remote method arguments,
        to implement file transfers as part of a remote call.
      </p>
<p>
        On the server-side, file transfer functionality is by default disabled, and
        needs to be explicitly enabled:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>

<span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>
</pre>
<p>
      </p>
<p>
        Here we've implemented a <code class="computeroutput"><span class="identifier">PrintAndDownload</span><span class="special">()</span></code> method, that allows clients to download
        files:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
    <span class="identifier">RCF_METHOD_V2</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">PrintAndDownload</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;,</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span><span class="special">)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="keyword">void</span> <span class="identifier">PrintAndDownload</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span> <span class="identifier">fileDownload</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="identifier">fileDownload</span> <span class="special">=</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span><span class="special">(</span><span class="string">"path/to/download"</span><span class="special">);</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        , which can be called like this:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileDownload</span> <span class="identifier">fileDownload</span><span class="special">(</span><span class="string">"path/to/download/to"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">PrintAndDownload</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">,</span> <span class="identifier">fileDownload</span><span class="special">);</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">pathToDownload</span> <span class="special">=</span> <span class="identifier">fileDownload</span><span class="special">.</span><span class="identifier">getLocalPath</span><span class="special">();</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileManifest</span> <span class="special">&amp;</span> <span class="identifier">downloadManifest</span> <span class="special">=</span> <span class="identifier">fileDownload</span><span class="special">.</span><span class="identifier">getManifest</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Client-local path to upload: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">pathToDownload</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Number of files uploaded: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">downloadManifest</span><span class="special">.</span><span class="identifier">mFiles</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
      </p>
<p>
        Here we've implemented a <code class="computeroutput"><span class="identifier">PrintAndUpload</span><span class="special">()</span></code> method, that allows clients to upload files:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
    <span class="identifier">RCF_METHOD_V2</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">PrintAndUpload</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;,</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileUpload</span><span class="special">)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="keyword">void</span> <span class="identifier">PrintAndUpload</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileUpload</span> <span class="identifier">fileUpload</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">pathToUpload</span> <span class="special">=</span> <span class="identifier">fileUpload</span><span class="special">.</span><span class="identifier">getLocalPath</span><span class="special">();</span>
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileManifest</span> <span class="special">&amp;</span> <span class="identifier">uploadManifest</span> <span class="special">=</span> <span class="identifier">fileUpload</span><span class="special">.</span><span class="identifier">getManifest</span><span class="special">();</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Server-local path to upload: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">pathToUpload</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Number of files uploaded: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">uploadManifest</span><span class="special">.</span><span class="identifier">mFiles</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
      </p>
<p>
        , which can be called like this:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Upload files to server.
</span><span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
<span class="identifier">RCF</span><span class="special">::</span><span class="identifier">FileUpload</span> <span class="identifier">fileUpload</span><span class="special">(</span><span class="string">"path/to/files"</span><span class="special">);</span>
<span class="identifier">client</span><span class="special">.</span><span class="identifier">PrintAndUpload</span><span class="special">(</span><span class="string">"Hello World"</span><span class="special">,</span> <span class="identifier">fileUpload</span><span class="special">);</span>
</pre>
<p>
      </p>
<p>
        File transfers can be monitored, paused, resumed, and canceled , and bandwidth
        throttles can be applied to file transfers to and from a given server.
      </p>
<p>
        For more information, see <a class="link" href="FileTransfers.html" title="File Transfers">File
        transfers</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.Protobufs"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.Protobufs" title="Protocol Buffers"> Protocol Buffers</a>
</h3></div></div></div>
<p>
        RCF provides native integration with <a href="http://code.google.com/p/protobuf/" target="_top">Protocol
        Buffers</a>. Classes that are generated by the Protocol Buffers compiler
        can be used in RCF interfaces, and serialization and deserialization is performed
        through the relevant Protocol Buffers functions.
      </p>
<p>
        For example, running the <code class="computeroutput"><span class="identifier">protoc</span></code>
        compiler over the following Protobuf interface:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="comment">// Person.proto
</span>
<span class="identifier">message</span> <span class="identifier">Person</span> <span class="special">{</span>
    <span class="identifier">required</span> <span class="identifier">int32</span> <span class="identifier">id</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
    <span class="identifier">required</span> <span class="identifier">string</span> <span class="identifier">name</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
    <span class="identifier">optional</span> <span class="identifier">string</span> <span class="identifier">email</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span>
<span class="special">}</span>

<span class="identifier">message</span> <span class="identifier">PbEmpty</span> <span class="special">{</span>
    <span class="identifier">optional</span> <span class="identifier">string</span> <span class="identifier">log</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">protoc</span> <span class="identifier">Person</span><span class="special">.</span><span class="identifier">proto</span> <span class="special">--</span><span class="identifier">cpp_out</span><span class="special">=.</span>
</pre>
<p>
      </p>
<p>
        , generates the C++ class <code class="computeroutput"><span class="identifier">Person</span></code>,
        defined in <code class="computeroutput"><span class="identifier">Person</span><span class="special">.</span><span class="identifier">pb</span><span class="special">.</span><span class="identifier">h</span></code>.
      </p>
<p>
        By including <code class="computeroutput"><span class="identifier">Person</span><span class="special">.</span><span class="identifier">pb</span><span class="special">.</span><span class="identifier">h</span></code>,
        we can send <code class="computeroutput"><span class="identifier">Person</span></code> instances
        to our <code class="computeroutput"><span class="identifier">Print</span><span class="special">()</span></code>
        function:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;../</span><span class="identifier">test</span><span class="special">/</span><span class="identifier">protobuf</span><span class="special">/</span><span class="identifier">messages</span><span class="special">/</span><span class="identifier">cpp</span><span class="special">/</span><span class="identifier">Person</span><span class="special">.</span><span class="identifier">pb</span><span class="special">.</span><span class="identifier">h</span><span class="special">&gt;</span>


<span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Person</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Person</span> <span class="special">&amp;</span> <span class="identifier">person</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Person name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">person</span><span class="special">.</span><span class="identifier">name</span><span class="special">();</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Person email: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">person</span><span class="special">.</span><span class="identifier">email</span><span class="special">();</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Person id: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">person</span><span class="special">.</span><span class="identifier">id</span><span class="special">();</span>
    <span class="special">}</span>
<span class="special">};</span>


<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="identifier">RcfClient</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;</span> <span class="identifier">client</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

    <span class="identifier">Person</span> <span class="identifier">person</span><span class="special">;</span>
    <span class="identifier">person</span><span class="special">.</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"Bob"</span><span class="special">);</span>
    <span class="identifier">person</span><span class="special">.</span><span class="identifier">set_email</span><span class="special">(</span><span class="string">"bob@acme.com"</span><span class="special">);</span>
    <span class="identifier">person</span><span class="special">.</span><span class="identifier">set_id</span><span class="special">(</span><span class="number">123</span><span class="special">);</span>
    <span class="identifier">client</span><span class="special">.</span><span class="identifier">Print</span><span class="special">(</span><span class="identifier">person</span><span class="special">);</span>
    
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        For more information on Protocol Buffers support, see <a class="link" href="ThirdParty.html#rcf_user_guide.ThirdParty.Protobufs" title="Protocol Buffers">Protocol
        Buffers</a>.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="rcf_user_guide.Tutorial.json_rpc"></a><a class="link" href="Tutorial.html#rcf_user_guide.Tutorial.json_rpc" title="JSON-RPC">JSON-RPC</a>
</h3></div></div></div>
<p>
        RCF provides a built in <a href="http://json-rpc.org/" target="_top">JSON-RPC</a>
        server, allowing access to C++ server functionality from JSON-RPC clients,
        such as Javascript code on web pages. RCF supports JSON-RPC over both HTTP
        and HTTPS.
      </p>
<p>
        RCF uses the <a href="http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx" target="_top">JSON
        Spirit</a> library to read and write JSON messages. You will need to
        download this library separately, and define <code class="computeroutput"><span class="identifier">RCF_USE_JSON</span></code>
        when building RCF, to enable JSON-RPC support (see <a class="link" href="AppendixBuilding.html" title="Appendix - Building RCF">Appendix
        - Building</a>).
      </p>
<p>
        To configure a JSON-RPC endpoint, call <code class="computeroutput"><span class="identifier">I_ServerTransport</span><span class="special">::</span><span class="identifier">setRpcProtocol</span><span class="special">()</span></code> on the relevant server transport. To expose
        servant objects to JSON-RPC clients, use <code class="computeroutput"><span class="identifier">RcfServer</span><span class="special">::</span><span class="identifier">bindJsonRpc</span><span class="special">()</span></code>.
      </p>
<p>
        Here is an example of a RCF server using multiple transports to accept both
        RCF requests and JSON-RPC requests:
      </p>
<p>
        
</p>
<pre class="programlisting"><span class="identifier">RCF_BEGIN</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">,</span> <span class="string">"I_HelloWorld"</span><span class="special">)</span>
    <span class="identifier">RCF_METHOD_V1</span><span class="special">(</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">Print</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;)</span>
<span class="identifier">RCF_END</span><span class="special">(</span><span class="identifier">I_HelloWorld</span><span class="special">)</span>

<span class="keyword">class</span> <span class="identifier">HelloWorldImpl</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">void</span> <span class="identifier">Print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">}</span>

    <span class="keyword">void</span> <span class="identifier">JsonPrint</span><span class="special">(</span>
        <span class="keyword">const</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">JsonRpcRequest</span> <span class="special">&amp;</span> <span class="identifier">request</span><span class="special">,</span> 
        <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">JsonRpcResponse</span> <span class="special">&amp;</span> <span class="identifier">response</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="comment">// Print out all the strings passed in, and return the number of
</span>        <span class="comment">// characters printed.
</span>
        <span class="keyword">int</span> <span class="identifier">charsPrinted</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>

        <span class="keyword">const</span> <span class="identifier">json_spirit</span><span class="special">::</span><span class="identifier">Array</span> <span class="special">&amp;</span> <span class="identifier">params</span> <span class="special">=</span> <span class="identifier">request</span><span class="special">.</span><span class="identifier">getJsonParams</span><span class="special">();</span>
        <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span> <span class="identifier">i</span><span class="special">&lt;</span><span class="identifier">params</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
        <span class="special">{</span>
            <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">params</span><span class="special">[</span><span class="identifier">i</span><span class="special">].</span><span class="identifier">get_str</span><span class="special">();</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"I_HelloWorld service: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
            <span class="identifier">charsPrinted</span> <span class="special">+=</span> <span class="identifier">s</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span>
        <span class="special">}</span>

        <span class="comment">// Return number of characters printed.
</span>        <span class="identifier">json_spirit</span><span class="special">::</span><span class="identifier">mObject</span> <span class="special">&amp;</span> <span class="identifier">responseObj</span> <span class="special">=</span> <span class="identifier">response</span><span class="special">.</span><span class="identifier">getJsonResponse</span><span class="special">();</span>
        <span class="identifier">responseObj</span><span class="special">[</span><span class="string">"result"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">charsPrinted</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>


<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfInitDeinit</span> <span class="identifier">rcfInit</span><span class="special">;</span>

    <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">RcfServer</span> <span class="identifier">server</span><span class="special">;</span>

    <span class="comment">// Accept RCF client requests on port 50001.
</span>    <span class="identifier">HelloWorldImpl</span> <span class="identifier">helloWorld</span><span class="special">;</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bind</span><span class="special">&lt;</span><span class="identifier">I_HelloWorld</span><span class="special">&gt;(</span><span class="identifier">helloWorld</span><span class="special">);</span>
    <span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">TcpEndpoint</span><span class="special">(</span><span class="number">50001</span><span class="special">)</span> <span class="special">);</span>

    <span class="comment">// Accept JSON-RPC requests over HTTP on port 80.
</span>    <span class="identifier">server</span><span class="special">.</span><span class="identifier">bindJsonRpc</span><span class="special">(</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&amp;</span><span class="identifier">HelloWorldImpl</span><span class="special">::</span><span class="identifier">JsonPrint</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">helloWorld</span><span class="special">,</span> <span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_2</span><span class="special">),</span> 
        <span class="string">"JsonPrint"</span><span class="special">);</span>

    <span class="identifier">server</span><span class="special">.</span><span class="identifier">addEndpoint</span><span class="special">(</span> <span class="identifier">RCF</span><span class="special">::</span><span class="identifier">HttpEndpoint</span><span class="special">(</span><span class="number">80</span><span class="special">)</span> <span class="special">)</span>
        <span class="special">.</span><span class="identifier">setRpcProtocol</span><span class="special">(</span><span class="identifier">RCF</span><span class="special">::</span><span class="identifier">Rp_JsonRpc</span><span class="special">);</span>

    <span class="identifier">server</span><span class="special">.</span><span class="identifier">start</span><span class="special">();</span>

    <span class="comment">// RCF clients can call Print() on port 50001.
</span>    <span class="comment">// ...
</span>    
    <span class="comment">// JSON-RPC clients can call JsonPrint() over HTTP on port 80.
</span>    <span class="comment">// ...
</span>
    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
      </p>
<p>
        For more information on JSON-RPC servers, see <a class="link" href="JsonRpc.html" title="JSON-RPC">JSON-RPC</a>.
      </p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2005 - 2016 Delta V Software</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="Intro.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="Clientside.html"><img src="../images/next.png" alt="Next"></a>
</div>
</body>
</html>
